﻿#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <regex>

// 化学方程式结构
struct ChemicalEquation {
    std::string reactants;  // 反应物
    std::string products;   // 生成物
    std::string condition;  // 反应条件
    std::string description; // 反应描述
};

// 化学方程式数据库
std::vector<ChemicalEquation> equationDatabase = {
    // 氧气相关反应
    {"C + O2", "CO2", "点燃", "碳完全燃烧生成二氧化碳"},
    {"2C + O2", "2CO", "点燃", "碳不完全燃烧生成一氧化碳"},
    {"S + O2", "SO2", "点燃", "硫燃烧生成二氧化硫，有刺激性气味气体产生"},
    {"4P + 5O2", "2P2O5", "点燃", "磷燃烧生成五氧化二磷，产生大量白烟"},
    {"3Fe + 2O2", "Fe3O4", "点燃", "铁在氧气中燃烧生成四氧化三铁，火星四射"},
    {"2Mg + O2", "2MgO", "点燃", "镁燃烧生成氧化镁，发出耀眼白光"},
    {"2H2 + O2", "2H2O", "点燃", "氢气燃烧生成水，产生淡蓝色火焰"},
    {"2Cu + O2", "2CuO", "加热", "铜在加热条件下与氧气反应生成黑色氧化铜"},

    // 氧气制取
    {"2KClO3", "2KCl + 3O2↑", "MnO2催化，加热", "氯酸钾分解制取氧气"},
    {"2KMnO4", "K2MnO4 + MnO2 + O2↑", "加热", "高锰酸钾分解制取氧气"},
    {"2H2O2", "2H2O + O2↑", "MnO2催化", "过氧化氢分解制取氧气"},

    // 氢气相关
    {"Zn + H2SO4", "ZnSO4 + H2↑", "常温", "锌与稀硫酸反应制取氢气"},
    {"Zn + 2HCl", "ZnCl2 + H2↑", "常温", "锌与稀盐酸反应制取氢气"},
    {"Fe + H2SO4", "FeSO4 + H2↑", "常温", "铁与稀硫酸反应生成氢气，溶液变为浅绿色"},
    {"Mg + H2SO4", "MgSO4 + H2↑", "常温", "镁与稀硫酸反应剧烈，生成氢气"},
    {"2Al + 3H2SO4", "Al2(SO4)3 + 3H2↑", "常温", "铝与稀硫酸反应生成氢气"},

    // 碳及其化合物
    {"C + 2CuO", "2Cu + CO2↑", "高温", "碳还原氧化铜，黑色粉末变红"},
    {"CO2 + C", "2CO", "高温", "二氧化碳与碳在高温下反应生成一氧化碳"},
    {"CO2 + H2O", "H2CO3", "常温", "二氧化碳溶于水生成碳酸，使紫色石蕊变红"},
    {"H2CO3", "CO2↑ + H2O", "常温/加热", "碳酸不稳定，分解生成二氧化碳和水"},
    {"CO2 + Ca(OH)2", "CaCO3↓ + H2O", "常温", "二氧化碳使澄清石灰水变浑浊"},
    {"CaCO3 + 2HCl", "CaCl2 + H2O + CO2↑", "常温", "实验室用大理石与稀盐酸制取二氧化碳"},
    {"CaCO3", "CaO + CO2↑", "高温", "高温煅烧石灰石生成生石灰和二氧化碳"},
    {"CO + CuO", "Cu + CO2", "加热", "一氧化碳还原氧化铜，黑色粉末变红"},
    {"CH4 + 2O2", "CO2 + 2H2O", "点燃", "甲烷燃烧生成二氧化碳和水，产生蓝色火焰"},
    {"C2H5OH + 3O2", "2CO2 + 3H2O", "点燃", "乙醇燃烧生成二氧化碳和水"},

    // 金属相关
    {"Fe + CuSO4", "FeSO4 + Cu", "常温", "铁与硫酸铜反应，铁表面有红色物质析出，溶液变浅绿"},
    {"Cu + 2AgNO3", "Cu(NO3)2 + 2Ag", "常温", "铜与硝酸银反应，铜表面有银白色物质析出"},
    {"Al + 3CuSO4", "Al2(SO4)3 + 3Cu", "常温", "铝与硫酸铜反应，铝表面有红色物质析出"},

    // 酸、碱、盐
    {"HCl + NaOH", "NaCl + H2O", "常温", "盐酸与氢氧化钠发生中和反应"},
    {"2HCl + Ca(OH)2", "CaCl2 + 2H2O", "常温", "盐酸与氢氧化钙反应"},
    {"H2SO4 + 2NaOH", "Na2SO4 + 2H2O", "常温", "硫酸与氢氧化钠反应"},
    {"HCl + AgNO3", "AgCl↓ + HNO3", "常温", "盐酸与硝酸银反应生成白色沉淀氯化银"},
    {"H2SO4 + BaCl2", "BaSO4↓ + 2HCl", "常温", "硫酸与氯化钡反应生成白色沉淀硫酸钡"},
    {"NaOH + HNO3", "NaNO3 + H2O", "常温", "氢氧化钠与硝酸发生中和反应"},
    {"Ca(OH)2 + Na2CO3", "CaCO3↓ + 2NaOH", "常温", "氢氧化钙与碳酸钠反应生成白色沉淀碳酸钙"},
    {"NaCl + AgNO3", "AgCl↓ + NaNO3", "常温", "氯化钠与硝酸银反应生成白色沉淀氯化银"},
    {"Na2SO4 + BaCl2", "BaSO4↓ + 2NaCl", "常温", "硫酸钠与氯化钡反应生成白色沉淀硫酸钡"},
    {"NH4Cl + NaOH", "NaCl + NH3↑ + H2O", "加热", "氯化铵与氢氧化钠反应生成有刺激性气味的氨气"},

    // 其他反应
    {"H2O + CaO", "Ca(OH)2", "常温", "生石灰与水反应生成熟石灰，放出大量热"},
    {"2H2O", "2H2↑ + O2↑", "通电", "电解水生成氢气和氧气，体积比约为2:1"},
    {"CuSO4·5H2O", "CuSO4 + 5H2O↑", "加热", "蓝色硫酸铜晶体受热分解生成白色硫酸铜粉末和水"},
    {"CuSO4 + 5H2O", "CuSO4·5H2O", "常温", "白色硫酸铜粉末遇水变蓝，可用于检验水的存在"}
};

// 从数据库中查找包含关键词的方程式
std::vector<ChemicalEquation> searchEquations(const std::string& keyword) {
    std::vector<ChemicalEquation> results;
    for (const auto& equation : equationDatabase) {
        if (equation.reactants.find(keyword) != std::string::npos ||
            equation.products.find(keyword) != std::string::npos ||
            equation.condition.find(keyword) != std::string::npos ||
            equation.description.find(keyword) != std::string::npos) {
            results.push_back(equation);
        }
    }
    return results;
}

// 显示方程式
void displayEquation(const ChemicalEquation& equation, int index) {
    std::cout << "\n" << (index + 1) << ". " << equation.reactants << " → "
        << equation.products << "\n";
    std::cout << "   反应条件: " << equation.condition << "\n";
    std::cout << "   描述: " << equation.description << "\n";
}

// 解析化学物质的组成元素
std::map<std::string, int> parseChemicalFormula(const std::string& formula) {
    std::map<std::string, int> elements;
    std::regex elementPattern("([A-Z][a-z]*)(\\d*)");

    auto words_begin = std::sregex_iterator(formula.begin(), formula.end(), elementPattern);
    auto words_end = std::sregex_iterator();

    for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
        std::smatch match = *i;
        std::string element = match[1].str();
        std::string countStr = match[2].str();
        int count = countStr.empty() ? 1 : std::stoi(countStr);

        elements[element] += count;
    }

    return elements;
}

// 检查方程式是否配平
bool isEquationBalanced(const ChemicalEquation& equation) {
    std::string reactantsStr = equation.reactants;
    std::string productsStr = equation.products;

    // 分割反应物和生成物
    std::vector<std::string> reactants;
    std::vector<std::string> products;

    size_t pos = 0;
    while ((pos = reactantsStr.find("+")) != std::string::npos) {
        reactants.push_back(reactantsStr.substr(0, pos));
        reactantsStr.erase(0, pos + 1);
    }
    reactants.push_back(reactantsStr);

    pos = 0;
    while ((pos = productsStr.find("+")) != std::string::npos) {
        products.push_back(productsStr.substr(0, pos));
        productsStr.erase(0, pos + 1);
    }
    products.push_back(productsStr);

    // 解析所有物质的元素组成
    std::map<std::string, int> reactantElements;
    std::map<std::string, int> productElements;

    for (const auto& reactant : reactants) {
        std::string formula = reactant;
        int coefficient = 1;

        // 提取系数
        size_t numEnd = 0;
        while (numEnd < formula.length() && std::isdigit(formula[numEnd])) {
            ++numEnd;
        }
        if (numEnd > 0) {
            coefficient = std::stoi(formula.substr(0, numEnd));
            formula = formula.substr(numEnd);
        }

        // 解析元素
        auto elements = parseChemicalFormula(formula);
        for (const auto& elem : elements) {
            reactantElements[elem.first] += elem.second * coefficient;
        }
    }

    for (const auto& product : products) {
        std::string formula = product;
        int coefficient = 1;

        // 提取系数
        size_t numEnd = 0;
        while (numEnd < formula.length() && std::isdigit(formula[numEnd])) {
            ++numEnd;
        }
        if (numEnd > 0) {
            coefficient = std::stoi(formula.substr(0, numEnd));
            formula = formula.substr(numEnd);
        }

        // 解析元素
        auto elements = parseChemicalFormula(formula);
        for (const auto& elem : elements) {
            productElements[elem.first] += elem.second * coefficient;
        }
    }

    // 检查元素数量是否相等
    return reactantElements == productElements;
}

int main() {
    std::cout << "==== 化学方程式查询器 ====\n";

    while (true) {
        std::cout << "\n请输入查询关键词 (输入q退出): ";
        std::string keyword;
        std::getline(std::cin, keyword);

        if (keyword == "q" || keyword == "Q") {
            std::cout << "感谢使用化学方程式查询器！\n";
            break;
        }

        auto results = searchEquations(keyword);

        if (results.empty()) {
            std::cout << "未找到包含 '" << keyword << "' 的化学方程式。\n";
            continue;
        }

        std::cout << "\n找到 " << results.size() << " 个相关方程式:\n";
        for (size_t i = 0; i < results.size(); ++i) {
            displayEquation(results[i], i);
        }

        // 询问是否需要检查配平
        std::cout << "\n是否需要检查某个方程式的配平情况？(输入编号，其他键跳过): ";
        std::string choice;
        std::getline(std::cin, choice);

        if (std::all_of(choice.begin(), choice.end(), ::isdigit)) {
            int index = std::stoi(choice) - 1;
            if (index >= 0 && index < static_cast<int>(results.size())) {
                bool balanced = isEquationBalanced(results[index]);
                std::cout << "方程式 \"" << results[index].reactants << " → "
                    << results[index].products << "\" 是"
                    << (balanced ? "" : "不") << "配平的。\n";
            }
        }
    }

    return 0;
}